"""
选择算子 
"""
import random
import numpy as np


def select1(pool, pops, fits, ranks, distances):
    """一对一锦标赛选择 选择算子
    Params:
        :param pool:新生成的种群大小
        :param pops:
        :param fits:
        :param ranks:
        :param distances:
        :return:
    """
    nPop, nChr = pops.shape
    nF = fits.shape[1]  # 适应度的目标函数是一个（100，2）维度的数组，此时nF=2
    newPops = np.zeros((pool, nChr))  # (100,3)zero矩阵
    newFits = np.zeros((pool, nF))  # (100,2)zero矩阵

    indices = np.arange(nPop).tolist()
    i = 0
    while i < pool:
        # <class 'list'>sample(list, k)返回一个长度为k新列表，新列表存放list所产生k个随机唯一的元素
        idx1, idx2 = random.sample(indices, 2)  # 随机挑选两个个体 
        idx = compare(idx1, idx2, ranks, distances)
        newPops[i] = pops[idx]
        newFits[i] = fits[idx]  # 将适应度函数也赋给新种群
        i += 1
    return newPops, newFits


def compare(idx1, idx2, ranks, distances):
    """ 比较算法，返回更好的idx下标索引；这说明，ranks被打乱后，只有索引对应，并没有重新排序
    Params:
        :param idx1: 对应数值的下标索引
        :param idx2:
        :param ranks:
        :param distances:
        :return: 更优的 idx
    """
    if ranks[idx1] < ranks[idx2]:
        idx = idx1
    elif ranks[idx1] > ranks[idx2]:
        idx = idx2
    else:
        if distances[idx1] <= distances[idx2]:
            idx = idx2
        else:
            idx = idx1
    return idx
